#ifndef __COMPRESOR_ARITMETICO_BASE_H__
#define __COMPRESOR_ARITMETICO_BASE_H__

#include <math.h>
#include <iostream>
#include "Modelo.h"
#include "../Aritmetico/ICompresor.h"

using namespace std;

class CompresorAritmeticoBase: public ICompresor
{
    public:

	virtual ~CompresorAritmeticoBase();

    virtual void comprimir(const Simbolo simbolo,const FrecuenciasSimbolos &frecuencias,
        const FrecuenciasSimbolos &excluir,std::ostream &salida);

    virtual void comprimirEquiprovable(const Simbolo simbolo,
        const FrecuenciasSimbolos &frecuencias,std::ostream &salida);

    virtual Simbolo descomprimir(const FrecuenciasSimbolos &frecuencias,
        const FrecuenciasSimbolos &excluir,std::istream &entrada);

    virtual Simbolo descomprimirEquiprovable(const FrecuenciasSimbolos &frecuencias,
        std::istream &entrada);

};

class CompresorAritmeticoQueCalcula:public CompresorAritmeticoBase
{
    public:

	CompresorAritmeticoQueCalcula();

	virtual ~CompresorAritmeticoQueCalcula();

	/**
	 * @pre Se llamo a PPMC::comprimir
	 * Muestra en pantalla el tamaño del archivo comprimido.
	 */
	virtual void mostrarTamanyoArchivoComprimido();

	virtual void addBitsACantidadTotal(const double probabilidad);

	virtual void comprimir(const Simbolo simbolo,const FrecuenciasSimbolos &frecuencias,
        const FrecuenciasSimbolos &excluir,std::ostream &salida);

    virtual void comprimirEquiprovable(const Simbolo simbolo,
        const FrecuenciasSimbolos &frecuencias,std::ostream &salida);

	protected:

    virtual double calcularFrecuenciaSimbolo(const DatoSimboloModelo &datoSimboloModelo);

	double cantidadTotalDeBitsUsados;

};

class CompresorAritmeticoEnjecimientoHiperbolico: public CompresorAritmeticoQueCalcula
{
	protected:

	virtual double calcularFrecuenciaSimbolo(const DatoSimboloModelo &datoSimboloModelo);
};

#endif
